package net.pws.oos.web.mobile;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.pws.common.jackson.JsonUtils;
import net.pws.common.util.HashUtils;
import net.pws.common.util.StringUtils;
import net.pws.oos.biz.BizException;
import net.pws.oos.biz.model.Attachment;
import net.pws.oos.biz.model.Checkin;
import net.pws.oos.biz.query.CheckinFinder;
import net.pws.oos.biz.query.parameter.CheckinQueryParameter;
import net.pws.oos.biz.service.CheckinService;
import net.pws.oos.security.SecurityUtils;
import net.pws.oos.web.dto.AttachmentDto;
import net.pws.oos.web.dto.CheckinDto;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/biz/mobile/checkin")
public class MobileCheckinAction extends AbstractAttachementAction {
    
    @Autowired
    private CheckinFinder checkinFinder;
    
    @Autowired
    private CheckinService checkinService;
    
    @RequestMapping("/save.json")
    @ResponseBody
    public Object saveCheckin(CheckinDto dto) {
        if (dto == null || StringUtils.isBlank(dto.getId())) {
            return JsonUtils.failedMap("未指定对应的考勤！");
        }
        
        try {
            Checkin model = entityManager.find(Checkin.class, dto.getId());
            if (model == null) {
                // 判断当天同类型签到是否已存在
                Date locateDate = dto.getLocateDate();
                if (locateDate == null) {
                    locateDate = dto.getCreateDateTime();
                    dto.setLocateDate(locateDate);
                }
                if (checkinFinder.hasCheckin(SecurityUtils.currentUserId(),
                                             dto.getType(),
                                             locateDate)) {
                    throw new BizException("当天已同类型考勤已提交，不能重复提交！");
                }
                dto.setExecPersonId(SecurityUtils.currentUserId());
                dto.setExecOrganId(SecurityUtils.currentUser().getOrganId());
                model = CheckinDto.to(dto, null, entityManager);
                model.setStatus(Checkin.IN_PROGRESS_STATUS);
            }
            else {
                if (Checkin.COMPLETED_STATUS.equals(model.getStatus())) {
                    throw new BizException("对应考勤的状态不正确！");
                }
                model.setName(dto.getName());
                model.setDescription(dto.getDescription());
                model.setLocateDate(dto.getLocateDate());
                model.setLongitude(dto.getLongitude());
                model.setLatitude(dto.getLatitude());
                model.setLocationProvice(dto.getLocationProvice());
                model.setLocationCity(dto.getLocationCity());
                model.setLocationCounty(dto.getLocationCounty());
                model.setLocationStreet(dto.getLocationStreet());
                model.setLocationNumber(dto.getLocationNumber());
                model.setLocationAddress(dto.getLocationAddress());
            }
            checkinService.save(model);
            return JsonUtils.succeedMap(model.getId());
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/attachment/upload.json")
    @ResponseBody
    public Object uploadCheckinAttachment(HttpServletRequest request,
                                          AttachmentDto dto) {
        if (StringUtils.isEmpty(dto.getResourceId())) {
            return JsonUtils.failedMap("未指定对应的考勤！");
        }
        
        MultipartFile file = dto.getFile();
        if (file == null || file.getSize() <= 0) {
            return JsonUtils.failedMap("上传的附件大小不正确！");
        }
        
        Checkin model = entityManager.find(Checkin.class, dto.getResourceId());
        
        // 根据MD5判断图片是否存在
        String checkCode = dto.getCheckCode();
        if (StringUtils.isBlank(checkCode)) {
            return JsonUtils.failedMap("上传的文件被破坏！");
        }
        Attachment attachment = attachmentFinder.getAttachment(checkCode,
                                                               model.getId());
        if (null != attachment) {
            // 图片已存在，直接当成功返回
            return JsonUtils.succeedMap(AttachmentDto.from(attachment));
        }
        
        // 检查上传的文件的校验码与提交的校验码是否一致
        String fileHash = null;
        try {
            fileHash = HashUtils.getHash(file.getInputStream(), "MD5");
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap("上传的文件被破坏！");
        }
        if (!checkCode.equals(fileHash)) {
            return JsonUtils.failedMap("上传的文件被破坏！");
        }
        
        // 保存附件到文件系统
        try {
            attachment = storeAttachment(dto, model);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return JsonUtils.succeedMap(AttachmentDto.from(attachment));
    }
    
    @RequestMapping("/commit.json")
    @ResponseBody
    public Object commitCheckin(String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonUtils.failedMap("未指定对应的考勤！");
        }
        
        Checkin model = checkinFinder.get(id);
        if (model == null) {
            return JsonUtils.failedMap("对应的考勤不存在！");
        }
        
        if (!Checkin.IN_PROGRESS_STATUS.equals(model.getStatus())) {
            return JsonUtils.failedMap("对应的考勤状态不正确！");
        }
        
        try {
            model.setStatus(Checkin.COMPLETED_STATUS);
            checkinService.save(model);
            return JsonUtils.succeedMap(id);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/list.json")
    @ResponseBody
    public Object listCheckin(CheckinQueryParameter param) {
        if (param == null) {
            param = new CheckinQueryParameter();
        }
        try {
            String userId = SecurityUtils.currentUserId();
            if (StringUtils.isEmpty(userId)) {
                throw new BizException("用户未登录！");
            }
            
            param.setExecPersonId(userId);
            param.setStatus(Checkin.COMPLETED_STATUS);
            List<Checkin> checkins = checkinFinder.list(param);
            return JsonUtils.succeedMap(CheckinDto.from(checkins));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/detail.json")
    @ResponseBody
    public Object getCheckin(String id) {
        if (StringUtils.isEmpty(id)) {
            return JsonUtils.failedMap("错误的参数！");
        }
        
        Checkin model = entityManager.find(Checkin.class, id);
        if (model == null) {
            return JsonUtils.failedMap("错误的参数！");
        }
        
        CheckinDto dto = CheckinDto.from(model);
        // 获得照片信息
        List<Attachment> attachments = attachmentFinder.getPhotos(id);
        if (attachments != null && attachments.size() > 0) {
            List<AttachmentDto> attDtos = AttachmentDto.from(attachments);
            for (AttachmentDto attDto : attDtos) {
                filterUri(attDto);
            }
            dto.setAttachments(attDtos);
        }
        
        return JsonUtils.succeedMap(dto);
    }
    
}
